package common

import (
	"container/list"
	"encoding/json"
	"fmt"
	"net"
	"strconv"
	"strings"
	"time"
)

var RiskInfos list.List
var weakAuthArr = [4]string{"mysql", "mssql", "ssh", "ftp"}
var innerIps [1][2]int64

func init() {
	innerIpA := inetAton("10.255.255.255")
	innerIps[0][0] = innerIpA
	innerIps[0][1] = 24
}

func SaveResult0(result string) {
	var info *RiskInfo
	info = new(RiskInfo)
	arr := strings.Split(result, " ")
	//1.判断 mysql，mssql，ssh，ftp 如果有的话 弱口令  RiskDetail 里面  mysql，mssql，ssh，ftp + weakauth
	selectRiskDetail(info, result, arr)
	//2. 第三个判断 条件 POC  CVE-2020-0796 SmbGhost = 对象 返回值'servicerisk'
	selectRiskType(info)
	info.LanIp = arr[1]
	info.Timestamp = time.Now().UnixNano() / 1e6
	data, _ := json.Marshal(info)
	s := string(data)
	fmt.Println("漏洞信息：" + s)
	RiskInfos.PushBack(info)
}

func SaveResult1(result string) {
	var info RiskInfo
	var isOut = false
	var isInner = false
	result = strings.ReplaceAll(result, "  ", "")
	result = strings.ReplaceAll(result, "[*]", "")
	result = strings.ReplaceAll(result, "[->]", "")
	arr := strings.Split(result, "\n")
	for i := 1; i < len(arr); i++ {
		//判断是否存在内网地址
		if IsInnerIp(arr[i]) {
			isInner = true
		}
		if checkIp(arr[i]) && strings.EqualFold(arr[i][0:strings.Index(arr[i], ".")], "20") {
			//以20开头的外网地址
			isOut = true
		}
	}
	if isInner && isOut {
		//符合包含以20开头的外网地址和10开头的内网地址条件的为内外网互联
		info.RiskDetail = "疑似内外网共联"
		info.RiskType = "system"
		info.LanIp = arr[1]
		info.Timestamp = time.Now().UnixNano() / 1e6
		RiskInfos.PushBack(info)
	}

}

/**
通过扫描的结果判断RiskDetail
*/
func selectRiskDetail(info *RiskInfo, result string, arr []string) {
	for _, key := range weakAuthArr {
		if strings.Contains(result, key) {
			info.RiskDetail = key + " weakauth"
			return
		}
	}
	for i := 2; i < len(arr); i++ {
		//Vulnerable不拼接到RiskDetail
		if !strings.EqualFold("Vulnerable", arr[i]) {
			info.RiskDetail = info.RiskDetail + arr[i] + " "
		}
	}
}

/**
  通过扫描的结果判断RiskType
*/
func selectRiskType(info *RiskInfo) {
	if strings.Contains(info.RiskDetail, "weakauth") || strings.Contains(info.RiskDetail, "CVE-2020-0796 SmbGhost") {
		info.RiskType = "system"
	} else {
		info.RiskType = "service"
	}
}

/**
判断是否是IP内网地址
*/
func IsInnerIp(ipStr string) bool {
	ipStr = strings.TrimSpace(ipStr)
	if !checkIp(ipStr) {
		return false
	}
	inputIpNum := inetAton(ipStr)
	for _, innerIp := range innerIps {
		if inputIpNum>>innerIp[1] == innerIp[0]>>innerIp[1] {
			return true
		}
	}
	return false
	//return inputIpNum>>24 == innerIpA>>24 || inputIpNum>>20 == innerIpB>>20 ||
	//	inputIpNum>>16 == innerIpC>>16 || inputIpNum>>22 == innerIpD>>22 ||
	//	inputIpNum>>24 == innerIpF>>24
}

// ip to int64
func inetAton(ipStr string) int64 {
	bits := strings.Split(ipStr, ".")
	if len(bits) != 4 {
		fmt.Println("不是有效IP", ipStr)
		return 0
	}

	b0, _ := strconv.Atoi(bits[0])
	b1, _ := strconv.Atoi(bits[1])
	b2, _ := strconv.Atoi(bits[2])
	b3, _ := strconv.Atoi(bits[3])

	var sum int64

	sum += int64(b0) << 24
	sum += int64(b1) << 16
	sum += int64(b2) << 8
	sum += int64(b3)

	return sum
}

func checkIp(ipStr string) bool {
	address := net.ParseIP(ipStr)
	if address == nil {
		//ip地址格式不正确
		return false
	} else {
		//ip地址格式正确
		return true
	}
}
